<?php

/**
 * BKloud Framework
 * Core_Application class
 * 
 * LICENSE:
 * BKloud Framework duoc xay dung va phat trien boi nhom BKloud - dai hoc bach khoa Ha Noi 
 * Ban duoc phep su dung framework nay cho muc dich hoc tap , nghien cuu va cac ung dung phi thuong mai
 * 
 * @copyright Copyright (c) 2011 BKloud - HPCC.
 * @version 0.1
 */

class Core_Http
{

    /**
     * Chuoi Url tu hostname toi noi chua file index.php
     *
     * @var string
     */
    private $_baseUrl;

    /**
     * Chuoi Url sau index.php
     *
     * @var string
     */
    private $_requestUri;

    /**
     * ten module
     *
     * @var string
     */
    private $_module;

    /**
     * ten controller
     *
     * @var string
     */
    private $_controller;

    /**
     * ten action
     *
     * @var string
     */
    private $_action;

    /**
     * Mang luu tru cap ten bien - gia tri : cac gia tri tren dia chi Url
     *
     * @var array
     */
    private $_arvs = array();


    public function __construct()
    {

        $this->setBaseUrl();
        $this->setRequestUri();
        $this->analyzeUri();
    }

    private function setBaseUrl()
    {

        $baseUrl = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';

        if ($baseUrl != '')
        {
            $pos = strpos($baseUrl, 'index.php');
            if ($pos !== false)
                $baseUrl = substr($baseUrl, 0, $pos);
            $baseUrl = trim($baseUrl, '/');
        }

        $this->_baseUrl = $baseUrl;
        
        $registry      = Core_Registry::singleton();
        if($baseUrl != '')
           $registry['baseUrl'] = '/' .$this->_baseUrl;
         else
           $registry['baseUrl'] = '';
    }

    public function getBaseUrl()
    {

        return $this->_baseUrl;
    }

    private function setRequestUri()
    {

        $requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        $requestUri = trim($requestUri, '/');

        if ($requestUri != '')
        {

            $baseUrl  = $this->_baseUrl;
            $indexUrl = $baseUrl . '/index.php';
            $pos      = strpos($requestUri, $indexUrl);

            if ($pos !== false)
            {
                $requestUri = substr($requestUri, strlen($indexUrl));
                $requestUri = trim($requestUri, '/');
                $baseUrl = '';
            }

            if ($baseUrl != '')
            {
                $pos = strpos($requestUri, $baseUrl);

                if ($pos !== false)
                {
                    $requestUri = substr($requestUri, strlen($baseUrl));
                    $requestUri = trim($requestUri, '/');
                }
            }
        }

        $this->_requestUri = $requestUri;
    }

    public function getRequestUri()
    {
        return $this->_requestUri;
    }

    public function getModule()
    {
        return $this->_module;
    }

    public function getController()
    {
        return $this->_controller;
    }

    public function getAction()
    {
        return $this->_action;
    }

    public function getArvs()
    {
        return $this->_arvs;
    }

    public function getParam($nameParam, $defaultValue = null)
    {
        if (isset($this->_arvs[$nameParam]))
            return $this->_arvs[$nameParam];
        return $defaultValue;
    }

    /**
     * Phan tich chuoi $_requestUri thanh cac module ,controller,action va mang gia tri arvs
     *
     * @return void
     */
    private function analyzeUri()
    {

        $requestUri = $this->getRequestUri();
        $requestUri = strtolower($requestUri);

        $registry      = Core_Registry::singleton();
        $defaultModule = $registry['config']['module']['default'];

        if ($requestUri != '')
        {
            $parts = explode('/', $requestUri);

            //ton tai module
            if ((!empty($parts)) && is_dir(APPLICATION_PATH . '/modules/' . $parts[0]))
            {

                $this->_module = $parts[0];
                array_shift($parts);
            } else
            {
                $this->_module = $defaultModule;
                if (!is_dir(APPLICATION_PATH . '/modules/' . $this->_module))
                    throw new Exception('Unable to load module: ' . $this->_module, 404);
            }


            //ton tai Controller
            if ((!empty($parts)) && is_readable(APPLICATION_PATH . '/modules/' . $this->_module . '/controllers/' . ucfirst($parts[0]) . 'Controller.php'))
            {

                $this->_controller = ucfirst($parts[0]) . 'Controller';
                array_shift($parts);
            } else
                $this->_controller = 'IndexController'; //gia tri mac dinh : IndexController

            $fileController = APPLICATION_PATH . '/modules/' . $this->_module .'/controllers/' . $this->_controller . '.php';
            if (!is_readable($fileController))
                throw new Exception('Unable to load controller: ' . $fileController, 404);
            include_once ($fileController);


            //ton tai phuong thuc action
            if ((!empty($parts)) && method_exists($this->_controller, ucfirst($parts[0]) .'Action'))
            {

                $this->_action = ucfirst($parts[0]) . 'Action';
                array_shift($parts);
            } else
            {
                $this->_action = 'indexAction'; // gia tri mac dinh : indexAction
                if (!method_exists($this->_controller, $this->_action))
                    throw new Exception('Unable to load action: ' . $this->_action . ' in file ' . $fileController,404);
            }


            if (!empty($parts))
            {
                if(count($parts)%2 == 1) throw new Exception("404 not found",404);
                for ($pos = 1; $pos < count($parts); $pos = $pos + 2)
                    $this->_arvs[$parts[$pos - 1]] = $parts[$pos];
            }
                
        } else
        {
            $this->_module = $defaultModule;
            $this->_controller = 'IndexController';
            $this->_action = 'indexAction';

            if (!is_dir(APPLICATION_PATH . '/modules/' . $this->_module))
                throw new Exception('Unable to load module: ' . $this->_module, 404);

            $fileController = APPLICATION_PATH . '/modules/' . $this->_module .'/controllers/' . $this->_controller . '.php';
            if (!is_readable($fileController))
                throw new Exception('Unable to load controller: ' . $fileController, 404);

            include_once ($fileController);
            if (!method_exists($this->_controller, $this->_action))
                throw new Exception('Unable to load action: ' . $this->_action . ' in file ' . $fileController,
                    404);
        }
    }
}
